/* eslint-disable import/no-dynamic-require */
/* eslint-disable no-console */
const path = require('path');
const chalk = require('chalk');
const webpack = require('webpack');
const express = require('express');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const historyFallback = require('connect-history-api-fallback');
const getPort = require('get-port');

const webpackConfig = require(`../config/webpack/webpack.${process.argv[2]}.conf.js`);

const start = async () => {
  const app = express();
  const port = await getPort({ port: process.env.PORT || getPort.makeRange(3000, 3100) });
  const server = app.listen(port, 'localhost', () => {
    const address = server.address().address;
    const url = `http://${address}:${port}/`;

    webpackConfig.output.publicPath(url);
    webpackConfig.entry('index').add('webpack-hot-middleware/client?overlay=false&noInfo=true');

    const compiler = webpack(webpackConfig.toConfig());

    const webpackDevMiddlewareInstance = webpackDevMiddleware(compiler, {
      noInfo: true,
      logLevel: 'warn',
      writeToDisk: true,
    });
    const webpackHotMiddlewareInstance = webpackHotMiddleware(compiler);

    app.use(historyFallback());

    // add CORS header
    app.use((req, res, next) => {
      if (req.url.match(/hot-update\.json$/)) {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
      }
      next();
    });

    app.use(webpackDevMiddlewareInstance);
    app.use(webpackHotMiddlewareInstance);
    app.use('/', express.static(path.join(__dirname, '../public')));

    console.log([
      chalk.bgMagentaBright.black(' INFO: '),
      chalk.bgBlueBright.black(' building now.... '),
    ].join(''));
    webpackDevMiddlewareInstance.waitUntilValid(() => {
      console.log([
        chalk.bgMagentaBright.black(' INFO: '),
        chalk.bgGreenBright.black(` dev server is now up at ${url} `),
      ].join(''));
    });
  });
};

start();
